﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SudokuGame.Logic
{
    class Sudoku
    {
        public int[,] initial, solution;

        //ВСЮДУ сначала номер столбца, затем - строки!!!
        public Sudoku(String text)
        {
            char[] txt = text.ToCharArray();
            Console.WriteLine(txt.Length);
            initial = new int[9,9];
            solution = new int[9, 9];
            for (int i = 0; i < 81; i++)
            {
                try
                {
                    initial[i % 9, i / 9] = Convert.ToInt32(Convert.ToString(txt[i]));
                    solution[i % 9, i / 9] = Convert.ToInt32(Convert.ToString(txt[i]));
                }
                catch (System.FormatException e)
                {
                    initial[i % 9, i / 9] = -1;
                    solution[i % 9, i / 9] = -1;
                }
            }
            

        }


        public bool removeFromSolution(int column, int line)
        {
            if (initial[column, line] == -1)
            {
                solution[column, line] = -1;
                return true;
            }
            return false;
        }


        public bool solved()
        {
            bool good = true;
            //Проверки на то, является ли solution решением.(ToDo)
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (solution[i, j] == -1) good = false;
                }
            }
            return good;
        }

        private bool check(int number, int column, int line)
        {
            
            for (int i = 0; i < 9; i++)
            {
                if (i != column && solution[i, line] == number) return false;
            }

            for (int j = 0; j < 9; j++)
            {
                if (j != line && solution[column, j] == number) return false;
            }

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {   
                    if ( ( i !=column%3 || j != line%3) 
                    && solution[3*(column/3)+i, 3*(line/3)+j] == number) return false;
                }
            }

            return true;
        }


        public bool addToSolution(int number, int column, int line)
        {
            bool good = check(number, column, line);
            if (good && initial[column,line] == -1) solution[column,line] = number;
            return good;
        }




        public void shiftLine(int line, int seed)
        {   
            int x = 0, y=1, z=2;
            shift(ref x, ref y, ref z, seed);
            int[] old = new int[3];
            for (int col = 0; col < 9; col++)
            {
                old[0] = initial[col, line * 3];
                old[1] = initial[col, line * 3+1];
                old[2] = initial[col, line * 3+2];
                initial[col, line * 3] = old[x];
                initial[col, line * 3 + 1] = old[y];
                initial[col, line * 3 + 2] = old[z];

                old[0] = solution[col, line * 3];
                old[1] = solution[col, line * 3+1];
                old[2] = solution[col, line * 3+2];
                solution[col, line * 3] = old[x];
                solution[col, line * 3 + 1] = old[y];
                solution[col, line * 3 + 2] = old[z];
            }
        }

        public void shiftCol(int col, int seed)
        {   
            int x = 0, y=1, z=2;
            shift(ref x, ref y, ref z, seed);
            int[] old = new int[3];
            for (int line = 0; line < 9; line++)
            {
                old[0] = initial[col * 3, line];
                old[1] = initial[col * 3 + 1, line];
                old[2] = initial[col * 3 + 2, line];
                initial[col * 3, line] = old[x];
                initial[col * 3+1, line] = old[y];
                initial[col * 3+2, line] = old[z];
                
                old[0] = solution[col * 3, line];
                old[1] = solution[col * 3 + 1, line];
                old[2] = solution[col * 3 + 2, line];
                solution[col * 3, line] = old[x];
                solution[col * 3+1, line] = old[y];
                solution[col * 3+2, line] = old[z];
                
            }
        }
        public void shiftBigLine(int seed){
            int x = 0, y=1, z=2;
            int[] old = new int[3];
            shift(ref x, ref y, ref z, seed);
            for (int col = 0; col < 9; col++)
            {
                for (int line = 0; line < 3; line++)
                {
                    old[0] = initial[col, line];
                    old[1] = initial[col, line + 3];
                    old[2] = initial[col, line + 6];
                    initial[col, line] = old[x];
                    initial[col, line + 3] = old[y];
                    initial[col, line + 6] = old[z];

                    old[0] = solution[col, line];
                    old[1] = solution[col, line + 3];
                    old[2] = solution[col, line + 6];
                    solution[col, line] = old[x];
                    solution[col, line + 3] = old[y];
                    solution[col, line + 6] = old[z];
                }
            }
        }
        public void shiftBigColumn(int seed)
        {
            int x = 0, y = 1, z = 2;
            int[] old = new int[3];
            shift(ref x, ref y, ref z, seed);
            for (int line = 0; line < 9; line++)
            {
                for (int col = 0; col < 3; col++)
                {
                    old[0] = initial[col, line];
                    old[1] = initial[col + 3, line];
                    old[2] = initial[col + 6, line];
                    initial[col, line] = old[x];
                    initial[col + 3, line] = old[y];
                    initial[col + 6, line] = old[z];

                    old[0] = solution[col, line];
                    old[1] = solution[col + 3, line];
                    old[2] = solution[col + 6, line];
                    solution[col, line] = old[x];
                    solution[col + 3, line] = old[y];
                    solution[col + 6, line] = old[z];
                }
            }
        }

        public void mirror(int seed)
        {   
            if (seed>1)
            {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < i; j++)
                {
                        initial[i, j] = initial[i, j] ^ initial[j, i];
                        initial[j, i] = initial[i, j] ^ initial[j, i];
                        initial[i, j] = initial[i, j] ^ initial[j, i];

                        solution[i, j] = solution[i, j] ^ solution[j, i];
                        solution[j, i] = solution[i, j] ^ solution[j, i];
                        solution[i, j] = solution[i, j] ^ solution[j, i];
                    }
                }
            }

            if( seed%2 == 0)
            {

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; i+j<8; j++)
                {
                   
                        initial[i, j] = initial[i, j] ^ initial[8-j, 8-i];
                        initial[8-j, 8-i] = initial[i, j] ^ initial[8-j, 8-i];
                        initial[i, j] = initial[i, j] ^ initial[8-j, 8-i];

                        solution[i, j] = solution[i, j] ^ solution[8-j, 8-i];
                        solution[8-j, 8-i] = solution[i, j] ^ solution[8-j, 8-i];
                        solution[i, j] = solution[i, j] ^ solution[8-j, 8-i];
                    
                    }
                }
            }

        }



        public void shift(ref int x, ref int y, ref int z, int seed)
        {
            int temp;
            switch (seed)
            {
                case 0:
                    { break; }
                case 1:
                    { temp = x; x = y; y = temp; break; }
                case 2:
                    { temp = y; y = z; z = x; x = temp; break; }
                case 3:
                    { temp = y; y = z; z = temp; break; }
                case 4:
                    { temp = z; z = y; y = x; x = temp; break; }
                case 5:
                    { temp = x; x = z; z = temp; break; }
            }
        }

    }
}
